package be.kuleuven.mume.query;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;

import be.kuleuven.mume.PMF;

public abstract class QueryHelper<T> {
	private static Logger log = Logger.getLogger(QueryHelper.class.getName());
	public boolean autoCloseQuery = true;
	private Exception e;
	private PersistenceManager pm;
	
	/**
	 * Atomic query will rollback changes if any error occurs.
	 * But the pm will complain of you fetch more than one objct.
	 * In that case use the executeQuery() method.
	 * @return
	 */
	public T executeAtomicQuery(){
		if(pm!=null) {
			log.log(Level.SEVERE, "QueryHelper", "Helper cannot execute twice");
			return null;
		}
		
		pm = PMF.getPersistenceManager();
		try {
			pm.currentTransaction().begin();
			
			T result = execute(pm);
			
			pm.currentTransaction().commit();
			if(autoCloseQuery)
				pm.close();
			return result;
		} catch (IllegalArgumentException e) {
			log.log(Level.INFO, "Need multiple entity? try use the executeQuery() method instead.");
			log.log(Level.SEVERE, "QueryHelper", e);
			pm.currentTransaction().rollback();
		} catch (Exception e) {
			log.log(Level.SEVERE, "QueryHelper", e);
			pm.currentTransaction().rollback();
		}
		return null;
	}
	
	public T executeQuery(){
		if(pm!=null) {
			log.log(Level.SEVERE, "QueryHelper", "Helper cannot execute twice");
			return null;
		}
		
		pm = PMF.getPersistenceManager();
		try {
			T result = execute(pm);
			
			if(autoCloseQuery)
				pm.close();
			return result;
		} catch (Exception e) {
			log.log(Level.SEVERE, "QueryHelper", e);
		}
		return null;
	}
	
	protected abstract T execute(PersistenceManager pm);
	
	public Exception getException(){
		return e;
	}
	
	public void close(){
		pm.close();
	}
}
